from typing import Callable, ContextManager
from sqlalchemy.orm import Session

from business_processes.opening_account_validation.domain.entity.package import (
    AccountPackage,
)
from business_processes.opening_account_validation.domain.service.check_package import (
    OpeningAccountCheckService,
)
from business_processes.opening_account_validation.infra.repository import PackageRepository
from business_processes.opening_account_validation.application.use_case.query import PackageQueryUseCase
from business_processes.opening_account_validation.presentation.rest.request import AccountPackageRequest


class AccountPackageCommandUseCase:
    def __init__(
        self,
        package_repo: PackageRepository,
        package_query: PackageQueryUseCase,
        package_processing_service: OpeningAccountCheckService,
        db_session: Callable[[], ContextManager[Session]],
    ):
        self.package_repo = package_repo
        self.package_query = package_query
        self.package_processing_service = package_processing_service
        self.db_session = db_session

    def execute(self, request: AccountPackageRequest) -> AccountPackage:
        package: AccountPackage = self.package_query.create_package_entity(
            package_request=request
        )

        validated_package = self.package_processing_service.run_business_process(
            package=package
        )

        with self.db_session() as session:
            self.package_repo.add(session=session, instance=validated_package)
            self.package_repo.commit(session=session)

        return validated_package
